package com.hulman.oms.service;

import com.hulman.oms.bean.*;
import com.hulman.oms.dao.RepairDao;
import com.hulman.oms.dao.RepairItemDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.SubjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author: maxwellens
 */
@Service
public class RepairItemService
{
    private static final String PROCESS_KEY = "repair";

    private static final String SUB_TAG = "repair-item";

    /**
     * 审核通过
     */
    private static final Integer AUDIT_OK = 1;

    /**
     * 审核不通过
     */
    private static final Integer AUDIT_NG = 2;

    @Autowired
    private RepairItemDao repairItemDao;
    @Autowired
    private RepairDao repairDao;
    @Autowired
    private UserService userService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private MsgService msgService;
    @Autowired
    private DeviceService deviceService;

    public List<RepairItem> findRepairItems(Map<String, Object> map)
    {
        return repairItemDao.findRepairItems(map);
    }

    public Integer findRepairItemsCount(Map<String, Object> map)
    {
        return repairItemDao.findRepairItemsCount(map);
    }

    public Result findRepairItemsResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = repairItemDao.findRepairItemsCount(map);
        List<RepairItem> data = repairItemDao.findRepairItems(map);
        return new Result(data, count);
    }

    public RepairItem findRepairItemById(Integer id)
    {
        return repairItemDao.findRepairItemById(id);
    }

    public void saveRepairItem(RepairItem repairItem)
    {
        if (repairItem.getId() != null && repairItem.getId() != 0)
        {
            repairItemDao.updateRepairItem(repairItem);
        } else
        {
            repairItemDao.insertRepairItem(repairItem);
        }
    }

    public void deleteRepairItemById(Integer id)
    {
        repairItemDao.deleteRepairItemById(id);
    }

    public void deleteRepairItems(int[] ids)
    {
        repairItemDao.deleteRepairItems(ids);
    }

    /**
     * 创建任务项
     *
     * @param repairId      任务工单ID
     * @param name          任务名称
     * @param executeByName 执行人
     */
    @Transactional(rollbackFor = Exception.class)
    public void create(Integer repairId, Integer deviceId, String deviceName, String deviceLocation, String name, String note, String executeByName, String notifyNames)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        User executeBy = userService.findUserByName(executeByName);
        if (executeBy == null)
        {
            throw new IoTException("不存在人员：" + executeByName);
        }
        //创建任务项
        RepairItem repairItem = new RepairItem();
        repairItem.setRepairId(repairId);
        repairItem.setDeviceId(deviceId);
        repairItem.setDeviceName(deviceName);
        repairItem.setDeviceLocation(deviceLocation);
        repairItem.setName(name);
        repairItem.setNote(note);
        repairItem.setExecuteById(executeBy.getId());
        repairItem.setExecuteByName(executeByName);
        repairItem.setNotifyNames(notifyNames);
        repairItem.setState(RepairItem.STATE_CREATED);
        repairItem.setAuditTimes(0);
        repairItemDao.insertRepairItem(repairItem);
        Repair repair = repairDao.findRepairById(repairItem.getRepairId());
        //创建任务项目
        Task task1 = new Task();
        task1.setProcInstId(repair.getProcInstId());
        task1.setOwnerId(user.getId());
        task1.setOwnerName(user.getName());
        task1.setName("创建维修项目");
        task1.setTag(PROCESS_KEY);
        task1.setSubTag(SUB_TAG);
        task1.addExtra("维修设备", repairItem.getDeviceName());
        task1.addExtra("维修描述", repairItem.getName());
        taskService.createAndCompleteTask(task1);
        //完成维修项目
        Task task2 = new Task();
        task2.setProcInstId(repair.getProcInstId());
        task2.setOwnerId(executeBy.getId());
        task2.setOwnerName(executeByName);
        task2.setName("完成维修项目");
        task2.setTag(PROCESS_KEY);
        task2.setSubTag(SUB_TAG);
        task2.setFormKey(repairItem.getId().toString());
        task2.addExtra("工单号", repair.getNo());
        task2.addExtra("维修设备", repairItem.getDeviceName());
        task2.addExtra("维修描述", repairItem.getName());
        taskService.addTask(task2);
        task2.setPath("/pages/repair/item?taskId=" + task2.getId());
        taskService.saveTask(task2);
        msgService.sendMsg(task2.toMsg());
        //通知相关人
        String[] notifyUserNames = notifyNames.split(",");
        for (String notifyName : notifyUserNames)
        {
            User notifyUser = userService.findUserByName(notifyName);
            if (notifyUser != null)
            {
                Msg msg = new Msg();
                msg.setTitle("新的维修项目");
                msg.addItem("维修设备", repairItem.getDeviceName());
                msg.addItem("维修描述", repairItem.getName());
                msg.addItem("备注", repairItem.getNote());
                msg.setType(Msg.TYPE_OM);
                msg.setPath("/pages/repair/item?id=" + repairItem.getId());
                msg.setCreateTime(new Date());
                msg.setState(Msg.STATE_UNREAD);
                msg.setOwnerId(notifyUser.getId());
                msg.setOwnerName(notifyUser.getName());
                msgService.sendMsg(msg);
            }
        }
    }

    /**
     * 任务工单ID
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void execute(Integer id)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        RepairItem repairItem = repairItemDao.findRepairItemById(id);
        Repair repair = repairDao.findRepairById(repairItem.getRepairId());
        repairItem.setStartTime(new Date());
        repairItem.setState(RepairItem.STATE_EXECUTING);
        repairItemDao.updateRepairItem(repairItem);

        Task task = new Task();
        task.setProcInstId(repair.getProcInstId());
        task.setOwnerId(user.getId());
        task.setOwnerName(user.getName());
        task.setName("执行维修项目");
        task.setTag(PROCESS_KEY);
        task.setSubTag(SUB_TAG);
        task.setName("执行维修项目");
        task.addExtra("维修设备", repairItem.getDeviceName());
        taskService.createAndCompleteTask(task);
    }

    /**
     * 暂存工单
     *
     * @param id         任务项ID
     * @param tools      工具
     * @param materials  材料
     * @param imgs       照片
     * @param completion 完成情况
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(Integer id, String vehicle, String driver, String tools, String materials, String deviceName, String deviceLocation, String imgs, String completion)
    {
        RepairItem repairItem = repairItemDao.findRepairItemById(id);
        if (repairItem == null)
        {
            throw new IoTException("不存在任务子项(id=" + id + ")");
        }
        repairItem.setVehicle(vehicle);
        repairItem.setDriver(driver);
        repairItem.setTools(tools);
        repairItem.setMaterials(materials);
        repairItem.setDeviceName(deviceName);
        repairItem.setDeviceLocation(deviceLocation);
        repairItem.setImgs(imgs);
        repairItem.setCompletion(completion);
        repairItemDao.updateRepairItem(repairItem);
    }

    /**
     * 完成工单
     *
     * @param taskId     任务ID
     * @param id         任务项ID
     * @param tools      工具
     * @param materials  材料
     * @param imgs       照片
     * @param completion 完成情况
     */

    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer taskId, Integer id, String vehicle, String driver, String tools, String materials, String deviceName, String deviceLocation, String imgs, String completion)
    {
        RepairItem repairItem = repairItemDao.findRepairItemById(id);
        //Repair repair = repairDao.findRepairById(repairItem.getRepairId());
        repairItem.setVehicle(vehicle);
        repairItem.setDriver(driver);
        repairItem.setTools(tools);
        repairItem.setMaterials(materials);
        repairItem.setDeviceName(deviceName);
        repairItem.setDeviceLocation(deviceLocation);
        repairItem.setImgs(imgs);
        repairItem.setCompletion(completion);
        repairItem.setEndTime(new Date());
        repairItem.setState(RepairItem.STATE_AUDITING);
        repairItemDao.updateRepairItem(repairItem);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
    }

    /**
     * 审核
     *
     * @param id           任务项ID
     * @param auditResult  审核结果
     * @param auditComment 审核意见
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(Integer id, Integer auditResult, String auditComment)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        RepairItem repairItem = repairItemDao.findRepairItemById(id);
        Repair repair = repairDao.findRepairById(repairItem.getRepairId());
        repairItem.setAuditResult(auditResult);
        repairItem.setAuditComment(auditComment);
        repairItem.setAuditTimes(repairItem.getAuditTimes() + 1);
        //审核通过
        if (auditResult == AUDIT_OK)
        {
            repairItem.setState(RepairItem.STATE_AUDITED);
            Task task = new Task();
            task.setProcInstId(repair.getProcInstId());
            task.setOwnerId(user.getId());
            task.setOwnerName(user.getName());
            task.setName("任务项审核通过");
            task.setTag(PROCESS_KEY);
            task.setSubTag(SUB_TAG);
            taskService.createAndCompleteTask(task);
            deviceService.refreshMaintainInfo(repairItem.getDeviceId());
        }
        //审核不通过
        else if (auditResult == AUDIT_NG)
        {
            repairItem.setState(RepairItem.STATE_EXECUTING);
            //创建新的任务
            Task task = new Task();
            task.setProcInstId(repair.getProcInstId());
            task.setOwnerId(repairItem.getExecuteById());
            task.setOwnerName(repairItem.getExecuteByName());
            task.setName("任务项审核不通过");
            task.setTag(PROCESS_KEY);
            task.setSubTag(SUB_TAG);
            task.setFormKey(repairItem.getId().toString());
            task.addExtra("任务名称", repairItem.getName());
            task.addExtra("审核意见", repairItem.getAuditComment());
            taskService.addTask(task);
            task.setPath("/pages/repair/item?taskId=" + task.getId());
            taskService.saveTask(task);
            msgService.sendMsg(task.toMsg());
        }
        repairItemDao.updateRepairItem(repairItem);
    }

    /**
     * 撤销
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancel(Integer id)
    {
        //删除任务项
        RepairItem repairItem = repairItemDao.findRepairItemById(id);
        repairItemDao.deleteRepairItemById(id);
        //删除关联任务
        Map<String, Object> map = new HashMap<>();
        map.put("subTag", SUB_TAG);
        map.put("name", "完成维修项目");
        map.put("formKey", repairItem.getId().toString());
        List<Task> tasks = taskService.findTasks(map);
        for (Task task : tasks)
        {
            taskService.deleteTaskById(task.getId());
        }
    }

    public static void main(String[] args)
    {
        StringJoiner sj = new StringJoiner(",");
        String result = sj.toString();
        System.out.println(result);
        System.out.println(String.join(",", "1", "2", "3"));
    }

}
